﻿using FB.Membership;
using FB.Providers;
using FB.Providers.EmployeeInfo;
using FCDB.Entity;
using FCDB.Repository;
using FCDB.Web.Models;
using FCDB.Web.Resources;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Script.Serialization;
using Wf5.Engine.Business;
using Wf5.Engine.Common;
using Wf5.Engine.Core;

namespace FCDB.Web.Controllers
{
    
    public class FormExternalController : Controller
    {
        protected IWorkflowService _wfService = new WorkflowService();
        protected FormRepository _formRepository = new FormRepository();
       
        private WfActivityInstanceRepository _wfActivityInstanceRespository = new WfActivityInstanceRepository();
        private WfProcessRepository wfProcessRepository = new WfProcessRepository();
        protected EmployeeInfoService _EMPInfoSvr = EmployeeInfoManager.GetEmployeeInfoService(); 
        protected FB.Services.MailService _mailService = new FB.Services.MailService(new FCDB.Web.Helpers.FCDBSmtpClientProxy());
        private WfActivityInstanceRepository activityRespository = new WfActivityInstanceRepository();
        protected EmployeeInfoUnit _EMPInfoUnit = EmployeeInfoManager.GetEmployeeInfoUnit();
      
       
        // GET: /FormExternal/
        protected Employee GetEmployeeByUserKey(Guid userID)
        {
            var efemployeeInfoProvider = AspNetEmployeeInfoProviderManager.Default as EFEmployeeInfoProvider;
            EmployeeInfoUnit unitinfo = efemployeeInfoProvider.GetEmployeeInfoUnit();
            Employee employee = unitinfo.EmployeeRepository.Get(t => t.UserID == userID).FirstOrDefault();
            if (employee == null)
            {
                employee = new Employee()
                {
                    ChineseName = "信息缺失用户",
                };
            }
            return employee;
        }
        /// <summary>
        /// 保存页面寄存ViewBase
        /// </summary>
        /// <param name="formId">表单的ID</param>
        /// <param name="AppInstanceID">流程的ID</param>
        protected void SaveCommonViewBase(long formId, long AppInstanceID,Guid? UserID)
        {


            String ProcessGuid = Request["ProcessGuid"];
            String FormType = (string)RouteData.Values["action"];
            ViewBag.FormAttachments = _formRepository.GetFormAttachments(FormType, formId);
            if (AppInstanceID == 0)
            {
                ViewBag.FormsRelations = _formRepository.GetFormsRelationsByForm(formId, FormType);
                ViewBag.FormCirculatedDocumentLogs = new List<FCDB.Entity.FormCirculatedDocumentLog>();
            }
            else
            {
                ViewBag.FormsRelations = _formRepository.GetFormsRelationsByProcess(new Guid(ProcessGuid), AppInstanceID);
                ViewBag.FormCirculatedDocumentLogs = _formRepository.GetDocumentLogs(new Guid(ProcessGuid), AppInstanceID);
            }
            ViewBag.FormUserID = UserID;

        }
        /// <summary>
        /// 获取流程审批节点和审批纪录
        /// </summary>
        /// <returns>返回流程节点</returns>
        protected IList<ActivityEntity> GetProcessActivitiesCheckLog()
        {
            String ProcessGuid = Request["ProcessGuid"];
            long AppInstanceID = 0;
            long.TryParse(Request["AppInstanceID"], out AppInstanceID);
            WfProcessInstance ProcessInstance = null;
            IList<FormCheckLog> checkLogs = null;
            ProcessModel processModel = new ProcessModel(new Guid(ProcessGuid));
            List<ActivityEntity> activitryList = new List<ActivityEntity>();
            IList<WfActivityInstance> appinstanceActivityList = null;
            IList<ActivityEntityModel> activityEntityModelList = new List<ActivityEntityModel>();
            if (AppInstanceID != 0)
            {
                ProcessInstance = _formRepository.Get<WfProcessInstance>(AppInstanceID);
                checkLogs = _formRepository.GetFormCheckLogs(AppInstanceID);
                appinstanceActivityList = _wfActivityInstanceRespository.GetProcessActivityList(AppInstanceID, new Guid(ProcessGuid));
            }
            Dictionary<string, string> conditionKeyPair = null;
            ActivityEntity activity = processModel.GetFirstActivity();
            IList<ActivityEntity> currentActivityList = new List<ActivityEntity>();
            NextActivityMatchedResult nextActivityResult = processModel.GetNextActivityList(activity, conditionKeyPair);
            foreach (var item in nextActivityResult.Root)
            {
                if (item.Transition.Condition != null && item.Transition.Condition.ConditionText.Trim() == "CheckState==2")
                {
                    continue;
                }
                currentActivityList.Add(item.Activity);
            }
            while (currentActivityList.Count > 0)
            {
                activity = currentActivityList[0];
                currentActivityList.Remove(activity);
                if (activitryList.Count(t => t.ActivityGUID == activity.ActivityGUID) > 0)
                {
                    continue;
                }
                if (activitryList.Count(t => t.ActivityGUID == activity.ActivityGUID) == 0 && activity.NodeType != NodeTypeEnum.EndNode && activity.NodeType != NodeTypeEnum.GatewayNode)
                {
                    activitryList.Add(activity);
                    if (ProcessInstance != null)
                    {
                        #region 添加审批节点纪录
                        //添加审批节点纪录
                        ActivityEntityModel model = new ActivityEntityModel(activity);
                        if (appinstanceActivityList.Count(t => t.ActivityGUID == activity.ActivityGUID) == 0)
                        {
                            model.NodeState = null;
                        }
                        else
                        {
                            WfActivityInstance instance = appinstanceActivityList.First(t => t.ActivityGUID == activity.ActivityGUID);
                            IList<FormCheckLog> logList = checkLogs.Where(t => t.ActivityInstanceGuid == activity.ActivityGUID).ToList();
                            FormCheckLog log = checkLogs.FirstOrDefault(t => t.ActivityInstanceGuid == activity.ActivityGUID);
                            model.NodeState = (NodeStateEnum)instance.State;
                            if (log != null)
                            {
                                model.CheckContent = log.CheckContent;
                                model.CheckState = (short)log.CheckState;
                                model.CheckUserID = log.CheckUserID;
                                model.CheckUserName = log.CheckUserName;
                                model.CheckUserID = log.CheckUserID;
                                model.CheckUserName = log.CheckUserName;
                                model.CheckTime = log.CheckTime;
                                model.CreateTime = log.CreateTime;
                                model.SendUserID = log.SendUserID;
                                model.SendUserName = log.SendUserName;
                                model.FormCheckLogList = logList;
                            }
                            else
                            {
                                model.CheckUserID = instance.EndedByUserID;
                                model.CheckUserName = instance.EndedByUserName;
                                model.CreateTime = instance.CreatedDateTime;
                                model.SendUserID = instance.CreatedByUserID;
                                model.SendUserName = instance.CreatedByUserName;
                            }
                            model.FromDiv = activity.FromDiv;
                        }
                        activityEntityModelList.Add(model);
                        #endregion
                    }
                }
                nextActivityResult = processModel.GetNextActivityList(activity, conditionKeyPair);
                foreach (var item in nextActivityResult.Root)
                {
                    if (currentActivityList.Count(t => t.ActivityGUID == item.Activity.ActivityGUID) == 0)
                    {
                        if (item.Transition.Condition != null && (item.Transition.Condition.ConditionText.Trim() == "CheckState==2" || item.Transition.Condition.ConditionText.Trim().IndexOf("CheckState==2") > -1))
                        {
                            continue;
                        }
                        else
                        {
                            currentActivityList.Add(item.Activity);
                        }
                    }
                }
            }
            activitryList = activitryList.OrderBy(t => t.Index).ToList();
            ViewBag.ActivitryEntityList = activitryList;
            if (ProcessInstance != null)
            {
                activityEntityModelList = activityEntityModelList.OrderBy(t => t.Index).ToList();
                ViewBag.ActivityCheckLogs = activityEntityModelList;
            }

            return activitryList;
        } 

        private void InitFormExtendInfo()
        {
            ViewBag.FormAttachments = new List<FormAttachment>();
            ViewBag.FormCirculatedDocumentLogs = new List<FCDB.Entity.FormCirculatedDocumentLog>();
            ViewBag.FormsRelations = new List<FormsRelation>();
            GetProcessActivitiesCheckLog();
            ViewBag.CurrentActivityGuid = Request["ActivityGuid"];
        }
     
        private void StartProcess(short? Status, Guid ProcessGuid, WfProcess process, long AppInstanceID,Guid UserId,
            string AppName = "")
        {
            var logger = NLog.LogManager.GetCurrentClassLogger();
            //logger.Info("Start StartProcess " + DateTime.Now.ToString("yyyy-MM-dd"));
            IList<Guid?> nUserIDList = new List<Guid?>();
            JavaScriptSerializer jsonConverter = new JavaScriptSerializer();
            String FormCondition = Request["FormConditionValue"]; 
            PerformerList pList = new PerformerList();
            IDictionary<string, string> conditionKeyPairs = new Dictionary<string, string>(); 
            ProcessModel processModel = new ProcessModel(ProcessGuid); 
            ActivityEntity activity = processModel.GetFirstActivity();
            ActivityEntity nextActivity = processModel.GetNextActivity(activity.ActivityGUID);
            #region 获取流程条件
            if (!String.IsNullOrEmpty(FormCondition))
            {
                List<KeyValueModel> conditions = jsonConverter.Deserialize<List<KeyValueModel>>(FormCondition);
                foreach (var item in conditions)
                {
                    conditionKeyPairs.Add(item.Key, item.Value);
                }
            }
            #endregion
            #region 获取审批用户 
            AspNetRoleProviderWrapper wapper = new AspNetRoleProviderWrapper();
            foreach (var roleItem in nextActivity.Roles)
            {
                IList<string> userList = wapper.FindAllUsers(roleItem);
                foreach (var useritem in userList)
                {
                    Employee employeeItem = this._EMPInfoUnit.EmployeeRepository.Get(t => t.UserName == useritem && t.UserID.HasValue).FirstOrDefault();
                    if (null != employeeItem)
                    {
                        pList.Add(new Performer(employeeItem.UserID,employeeItem.ChineseName));
                        nUserIDList.Add(employeeItem.UserID);
                        continue; 
                    }
                }
            } 
            #endregion
            #region 流程
            if (Status == (short)FormStatusEnum.Working)
            {
                var initial = new WfAppRunner();
                initial.AppInstanceID = AppInstanceID;
                initial.ProcessGUID = ProcessGuid;
                initial.UserID = UserId; 
                initial.UserName = GetEmployeeByUserKey(UserId).ChineseName;
                initial.AppName = AppName;
                WfExecutedResult result = _wfService.StartProcess(initial);
                if (result.Status == WfExecutedStatus.Successed)
                {  
                    initial.NextActivityPerformers = new Dictionary<Guid, PerformerList>(); 
                    initial.NextActivityPerformers.Add(nextActivity.ActivityGUID, pList);
                    _wfService.RunProcessApp(initial);
                    SendEmail(nUserIDList, (int)initial.AppInstanceID);
                }
            }
            //logger.Info("End StartProcess " + DateTime.Now.ToString("yyyy-MM-dd"));
            #endregion
        }
       
        void SendEmail(IList<Guid?> userIdList, int appInstance)
        {
            if (userIdList == null || userIdList.Count == 0) return;
            WfProcessInstance Instance = _wfService.GetProcessInstance(appInstance);
            IEnumerable<WfActivityInstance> activityInstanceList = activityRespository.GetProcessRunningActivityList((long)appInstance, Instance.ProcessGUID);
            var logger = NLog.LogManager.GetCurrentClassLogger();

            string url = ConfigurationManager.AppSettings["FCDBHostDomain"];
            foreach (var item in userIdList)
            {
                var ToPeople = _EMPInfoUnit.EmployeeRepository.Get(t => t.UserID == item && t.UserID != null).FirstOrDefault();
                if (null != ToPeople)
                {
                    if (string.IsNullOrEmpty(ToPeople.Email)) return;
                    var mail = new FCDB.Web.EmailModel.NotificationMailModel
                    {
                        From = FCDB.Web.Helpers.AppSettings.Email_Sender,
                        IsBodyHtml = true,
                    };

                    mail.To.Add(ToPeople.Email);
                    mail.Subject = string.Format(EmailSubject.WorkflowProcess, Instance.CreatedByUserName, Instance.ProcessName); //"单据：{0} 的 {1} 请你审批！"
                    mail.FOAHostDomain = url;
                    mail.UserName = ToPeople.ChineseName;
                    mail.ProcessName = Instance.AppName;
                    mail.FOAHostDomain = url;
                    mail.ProcessType = Instance.ProcessName;
                    if (activityInstanceList != null && activityInstanceList.Count() > 0)
                    {
                        mail.Node = activityInstanceList.First().ActivityName;
                    }
                    else
                    {
                        mail.Node = "你的待办";
                    }
                    var template = Path.Combine(ConfigurationManager.AppSettings["HtmlTemplateFolder"], "check.html");
                    _mailService.SendEmailNotification(template, mail);
                }
            }

        }
      

    }
}
